import { apiUrl }                         from         '@/api/url';
import { wsRouter }                       from         '@/api/enmu';
import { lang }                           from         '@/workers/util/http';
import $http                              from         '@/workers/util/http';
import { compare,accAdd,countNum,formatDate,accMul }          from '@/workers/util/util';

let publicSocket = null;            // socket连接信息
let pingCount = 0;                  // ping次数
let pongCount = 0;                  // pong次数
let currentId = '';                 // 当前订阅的币种
let pingPongTimer = null;           // pingPong定时器
let connectTimer = null;            // ws连接定时器
let type = '';                      // 当前合约信息  SwapU  SwapC  SwapB  Swap
let SwapUObj = {};                  // USDT永续所有币种
let SwapCObj = {};                  // USDC永续所有币种
let SwapBObj = {};                  // BUSD永续所有币种
let SwapObj = {};                   // USD永续所有币种
let currentConfig = {};             // 当前币种配置信息

let tradeList = [];                 // 实时成交临时存放
let tradeListLen = 50;              // 实时成交最大数量

let pageStatus = true;              // 页面是否展示在前台
let router = '';                    // 当前页面路由

let panList = [];
let sliceAmount = 25;               // 买卖盘口档位
let deepValue = '';
let panPriceNum = 2;                // 盘口小数位

let swapUTempPO = [];               // 临时存放SwapU价格列表
let swapCTempPO = [];               // 临时存放SwapC价格列表
let swapBTempPO = [];               // 临时存放SwapB价格列表
let swapTempPO = [];                // 临时存放Swap价格列表

let swapUmarketData = [];           // USDT永续所有币种快照
let swapCmarketData = [];           // USDC永续所有币种快照
let swapBmarketData = [];           // BUSD永续所有币种快照
let swapMarketData = [];            // 币本位合约所有币种快照

let lastKline = {};                 // 最后一根K线
let resolution = '';                // K线周期
let nextKlineDate = '';             // 下一个K线日期
let currentBegintTime = '';         // 当前实时推送使用的K线时间
let nextBegintTime = '';            // 下一根推送使用的K线时间
let _maxVolume = 0,_preVolume = 0;
let timeNav = [];

let liveList = [];                  // 正在推送价格的币种列表
let livePriceList = [];             // 临时缓存的币种价格列表
let sendPricesTemp = '';            // 接收价格时刻时间戳

//定时器推送
let getOrderBookTemp = '';          // 获取到盘口时间
let marketListTimer = null;
let swapUPriceTimer = null;
let swapCPriceTimer = null;
let swapBPriceTimer = null;
let swapPriceTimer = null;

let connectErrTimes = 0;            // 连接异常错误次数
let onLine = true;                  // 当前是否连接网络
let baseTimeout = 10*1000;          // ws连接超时时间
let getPriceByHttpTimer = null;     // 轮询获取币种价格定时器
let subByCacheTime = '';            // 执行根据缓存订阅时间

// 当前币种订阅缓存信息
let currentIdCacheMsg = {
    action:'-1',
};
// K线订阅缓存信息
let klineCacheMsg = {
    action:'-1',
    value:''
};
// 实时成交订阅缓存信息
let tradeListCacheMsg = {
    action:'-1'
};
// 盘口订阅缓存信息
let panListCacheMsg = {
    action:'-1',
    InstrumentID:'',
};

function transferFn(_resolution) {
    _resolution = _resolution+'';
    if(_resolution == '-1'){
        return '1m'
    }else if(_resolution.includes('m')){
        return _resolution.slice(0,_resolution.length-1)+'m'
    }else if(_resolution.includes('H')){
        return _resolution.slice(0,_resolution.length-1)+'h'
    }else if(_resolution.includes('D')){
        return _resolution.slice(0,_resolution.length-1)+'d'
    }else if(_resolution.includes('W')){
        return _resolution.slice(0,_resolution.length-1)+'w'
    }else if(_resolution.includes('M')){
        return _resolution.slice(0,_resolution.length-1)+'o'
    }else if(Number(_resolution < 60)){
        return _resolution+'m'
    }else{
        return Math.floor(_resolution/60)+'h'
    }
}

function calcNextKlineDate(_currentBegintTime) {
    //计算下一个需要更新的K线日期
    let find = timeNav.find(item => item.code === resolution);
    nextBegintTime = find?find.id*60 + _currentBegintTime:_currentBegintTime;
    postMessage({
        type:type,
        action:'calcNextKlineDate',
        value:nextBegintTime
    })
}


function postMarketList(){
    // 推送实时成交列表
    // item.Direction  0:买   1  卖
    if(tradeList.length){
        while (tradeList.length < tradeListLen) {
            tradeList.push({
                d:{
                    D:0,
                    I:0,
                    P:0,
                    T:0,
                    V:0
                }
            })
        }
        while (tradeList.length > tradeListLen) {
            tradeList.pop();
        }
        let list = [];
        for(let item of tradeList){
            let _data = {
                Direction:item.d.D,
                InstrumentID:item.d.I,
                Price:countNum(item.d.P,currentConfig.PriceNum?currentConfig.PriceNum:0),
                TradeTime:formatDate(item.d.T),
                Volume:parseInt(item.d.V),
            }
            _data.LastPrice = _data.Price;
            list.push(_data)
        }
        postMessage({
            type:type,
            action:'tradeList',
            value:list
        })
    }
}

function sendOrderBook(){
    //推送盘口数据
    //过滤askList
    let _askList = panList.filter(item => item.Direction==='0').sort(compare('Price',1));
    while (_askList.length < sliceAmount) {
        _askList.push({
            Price:0,
            Volume:0,
            TotalVolume:0
        })
    }
    while (_askList.length > sliceAmount) {
        _askList.pop();
    }
    //计算总数
    _askList.map((item,index,arr) => {
        if(currentConfig && currentConfig.Type && deepValue && deepValue.toString().includes('.')) item.Price = countNum(item.Price,panPriceNum);
        item.TotalVolume = index==0?item.Volume: accAdd(arr[index].Volume,arr[index-1]?arr[index-1].TotalVolume:0,3);
    });

    //过滤bidList
    let _bidList = panList.filter(item => item.Direction==='1').sort(compare('Price',0));
    //计算总数
    _bidList.map((item,index,arr) => {
        if(currentConfig && currentConfig.Type && deepValue && deepValue.toString().includes('.')) item.Price = countNum(item.Price,panPriceNum);
        item.TotalVolume = index==0?item.Volume: accAdd(arr[index].Volume,arr[index-1]?arr[index-1].TotalVolume:0,3);
    });
    while (_bidList.length < sliceAmount) {
        _bidList.push({
            Price:0,
            Volume:0,
            TotalVolume:0
        })
    }
    while (_bidList.length > sliceAmount) {
        _bidList.pop();
    }
    // _bidList.reverse();

    postMessage({
        type:type,
        action:'panList',
        value:{
            askList:_askList,
            bidList:_bidList
        }
    })
}

function postCurrentIdInfo(item){
    // 推送当前币种最新价格
    // 洗数据
    let _data = {
        Type : item.G,
        InstrumentID : item.I,
        HighestPrice : item.H,
        Price:item.N,
        LastPrice : item.N,
        LowerLimitPrice : item.F,
        LowestPrice : item.L,
        MarkedPrice : item.M,
        OpenInterest : item.P,
        OpenPrice : item.O,
        UpdateTime : item.U,
        UpperLimitPrice : item.C,
        Volume : item.V,
        UnderlyingPrice : item.D,
        PositionFeeRate : item.R,
        PrePositionFeeRate : item.E,
        TradeTime:item.U,
        PerSymbol:'--',
        Percent:'--',
        localePrice:'--',
        AP1:item.AP1,
        BP1:item.BP1,
        PositionFeeTime:item.PF,        //资金费率结算时间
    }
    if(!currentConfig) currentConfig = type==='SwapU'?SwapUObj[currentId]:type==='Swap'?SwapObj[currentId]:type==='SwapC'?SwapCObj[currentId]:type==='SwapB'?SwapBObj[currentId]:{};
    if(currentConfig && currentConfig.InstrumentName) _data.InstrumentName = currentConfig.InstrumentName;
    if(currentConfig && currentConfig.InstrumentID && _data.InstrumentID === currentId && currentId === currentConfig.InstrumentID) {
        //小数点控制
        _data.Price = countNum(_data.Price,currentConfig.PriceNum?currentConfig.PriceNum:0)
        _data.Volume = countNum(_data.Volume,currentConfig.PanVolumeNum?currentConfig.PanVolumeNum:0)
        if(_data.HighestPrice) _data.HighestPrice = countNum(_data.HighestPrice,currentConfig.PriceNum?currentConfig.PriceNum:2);
        if(_data.LastPrice) _data.LastPrice = countNum(_data.LastPrice,currentConfig.PriceNum?currentConfig.PriceNum:2);
        if(_data.MarkedPrice) _data.MarkedPrice = countNum(_data.MarkedPrice,currentConfig.PriceNum?currentConfig.PriceNum:2);
        if(_data.Volume) _data.Volume = countNum(_data.Volume,currentConfig.PanVolumeNum?currentConfig.PanVolumeNum:2);
        //百分比
        let _percent = '--';
        if(_data.Price && _data.OpenPrice && _data.OpenPrice != '--'){
            _percent = countNum((Math.abs(Number(_data.Price)-Number(_data.OpenPrice))/_data.OpenPrice)*100,2);
        }
        _data.Percent = _percent;                                   
        //百分比符号
        _data.PerSymbol = _data.OpenPrice != '--'?(Number(_data.Price) >= Number(_data.OpenPrice)?'+':'-'):'';
        postMessage({
            type:type,
            action:'marketItem',
            value:_data
        })
    }
}

function sendPriceList(){
    // 更新SwapC
    let list = [];
    for(let item of livePriceList){
        let _item = {
            Type : item.d.G,
            InstrumentID : item.d.I,
            HighestPrice : item.d.H,
            LastPrice : item.d.N,
            LowerLimitPrice : item.d.F,
            LowestPrice : item.d.L,
            MarkedPrice : item.d.M,
            OpenInterest : item.d.P,
            OpenPrice : item.d.O,
            UpdateTime : item.d.U,
            UpperLimitPrice : item.d.C,
            Volume : item.d.V,
            UnderlyingPrice : item.d.D,
            PositionFeeRate : item.d.R,
            PrePositionFeeRate : item.d.E,
            AP1:item.d.AP1,
            BP1:item.d.BP1,
        }
        if(_item.OpenPrice && _item.LastPrice){
            // 计算百分比
            _item.Percent = _item.OpenPrice?countNum((Math.abs(Number(_item.LastPrice)-Number(_item.OpenPrice))/_item.OpenPrice)*100,2):'-';
            _item.PerSymbol = _item.LastPrice > _item.OpenPrice?'+':_item.LastPrice < _item.OpenPrice?'-':'';
        }
        //查找或缓存当前币种配置信息
        let cConfig = {};
        if(_item.Type === 'SwapU' && SwapUObj[_item.InstrumentID]) cConfig = SwapUObj[_item.InstrumentID];
        if(_item.Type === 'SwapB' && SwapBObj[_item.InstrumentID]) cConfig = SwapBObj[_item.InstrumentID];
        if(_item.Type === 'SwapC' && SwapCObj[_item.InstrumentID]) cConfig = SwapCObj[_item.InstrumentID];
        if(_item.Type === 'Swap' && SwapObj[_item.InstrumentID]) cConfig = SwapObj[_item.InstrumentID];
        //小数位数控制
        if(_item.HighestPrice) _item.HighestPrice = countNum(_item.HighestPrice,cConfig.PriceNum?cConfig.PriceNum:2);
        if(_item.LastPrice) _item.LastPrice = countNum(_item.LastPrice,cConfig.PriceNum?cConfig.PriceNum:2);
        if(_item.MarkedPrice) _item.MarkedPrice = countNum(_item.MarkedPrice,cConfig.PriceNum?cConfig.PriceNum:2);
        if(_item.Volume) _item.Volume = countNum(_item.Volume,cConfig.PanVolumeNum?cConfig.PanVolumeNum:2);

        //新增或更新
        let find = list.find(ele => ele.InstrumentID === _item.InstrumentID);
        if(find){
            find.HighestPrice = _item.HighestPrice;
            find.LastPrice = _item.LastPrice;
            find.LowerLimitPrice = _item.LowerLimitPrice;
            find.LowestPrice = _item.LowestPrice;
            find.MarkedPrice = _item.MarkedPrice;
            find.OpenInterest = _item.OpenInterest;
            find.OpenPrice = _item.OpenPrice;
            find.UpdateTime = _item.UpdateTime;
            find.UpperLimitPrice = _item.UpperLimitPrice;
            find.Volume = _item.Volume;
            find.UnderlyingPrice = _item.UnderlyingPrice;
            find.PositionFeeRate = _item.PositionFeeRate;
            find.PrePositionFeeRate = _item.PrePositionFeeRate;
        }else{
            list.push(_item)
        }
    }
    if(list.length){
        postMessage({
            type:'SwapU',
            action:'marketData',
            value:list,
        })
    }
    list = [];
    livePriceList = [];
}

function calc(ev){
    // 计算ws返回数据
    if(ev.data === 'zip_ready_for_1') return
    if(ev.data === 'pong'){
        pongCount++;
    }else{ 
        if(ev && ev.data != 'input error' && ev.data && ev.data.includes('{')){
            let res = [];
            try{
                res = JSON.parse(ev.data);
            }catch(e){
                console.log('socket返回JSON数据格式错误')
            }
            if(Array.isArray(res)) return
            // 当前币种价格
            if(res.a === 'PO'){
                if(Array.isArray(res.r)){
                    let find = res.r.find(ele => ele.d.I === currentId);
                    if(find) postCurrentIdInfo(find.d);
                    // 缓存起来
                    livePriceList = livePriceList.concat(res.r);
                    if(!sendPricesTemp) {
                        sendPriceList();
                        sendPricesTemp = +new Date();
                        // console.log((new Date()).getSeconds())
                    }else{
                        let delayTime = pageStatus?50:6000;
                        if(+new Date() - sendPricesTemp >= delayTime){
                            sendPriceList();
                            sendPricesTemp = +new Date();
                        }
                    }
                }
            }

            //实时成交
            if(res.a === 'PMT'){
                if(Array.isArray(res.r)){
                    tradeList = res.r.concat(tradeList);
                    postMarketList();
                }
            }

            //盘口
            if(res.a === 'PMO'){
                // Direction  0:买   1:卖
                let _requestNo = res.hasOwnProperty('m')?0:1;                //判断是否初始化盘口 0:是  1:非
                let result = res.r;
                let newPanList = [];
                for(let i=0;i<result.length;i++){
                    let obj = result[i].d;
                    if(obj.I === currentId){
                        let item = {
                            InstrumentID:result[i].d.I,
                            Direction:result[i].d.D,
                            Volume:result[i].d.V,
                            Price:result[i].d.P,
                        }
                        //只有当前币种的信息才可以继续
                        if(_requestNo === 0){
                            //初始化
                            newPanList.push({
                                Price:item.Price,
                                Volume:item.Volume,
                                TotalVolume:0,
                                InstrumentID: item.InstrumentID,
                                Direction:item.Direction,
                            })
                        }else{
                            let _findIndex = panList.findIndex(ele => Number(ele.Price) === Number(item.Price) && ele.Direction === item.Direction);
                            if(_findIndex > -1){
                                //存在价格相同的数据
                                let _find = panList.find(ele => Number(ele.Price) === Number(item.Price) && ele.Direction === item.Direction);
                                if(!Number(item.Volume)){
                                    //若新数据成交量为0，则直接删除
                                    panList.splice(_findIndex,1)
                                }else{
                                    //新价格有成交量，则替换原数据中的量
                                    _find.Volume = item.Volume;
                                }
                            }else{
                                // 新数据
                                // 没最新价的时候   买入价低于或等于实时价   卖出价高于或等于实时价
                                if(item.Volume > 0){
                                    newPanList.push({
                                        Price:item.Price,
                                        Volume:item.Volume,
                                        TotalVolume:0,
                                        InstrumentID: item.InstrumentID,
                                        Direction:item.Direction,
                                    })
                                }
                            }
                        }
                    }
                }
                let newArr = newPanList.concat(panList);
                panList = _requestNo === 0?newPanList:newArr;
                sendOrderBook();
                // console.log((new Date()).getSeconds())
                // 推送逻辑
                // if(_requestNo === 0){
                //     // 初始化
                //     sendOrderBook();
                //     getOrderBookTemp = +new Date();
                //     console.log((new Date()).getSeconds())
                // }else{
                //     if(+new Date() - getOrderBookTemp >= 200){
                //         sendOrderBook();
                //         getOrderBookTemp = +new Date();
                //         console.log((new Date()).getSeconds())
                //     }
                // }
            }

            //实时K线
            if(res.a === 'PK'){
                if(Array.isArray(res.r)){
                    let list = [];
                    for(let ele of res.r){
                        if(ele.d.I === currentId){
                            let item = {
                                BeginTime:ele.d.B,
                                ClosePrice:ele.d.C,
                                HighestPrice:ele.d.H,
                                InstrumentID:ele.d.I,
                                LowestPrice:ele.d.L,
                                // M:ele.d.M,
                                OpenPrice:ele.d.O,
                                PeriodID:ele.d.P,
                                Volume:ele.d.V,
                                // ExchangeID
                            }
                            let periodID = item.PeriodID
                            if (resolution === '1') {
                                //一分钟数据实时更新
                                if (item.InstrumentID === currentId) {
                                    lastKline = item;
                                    postMessage({
                                        type:type,
                                        action:'Kline',
                                        value:item
                                    })
                                }
                            } else {
                                if (transferFn(resolution) === periodID) {
                                    //首次会话得到的K线推送
                                    _maxVolume = item.Volume;
                                    _preVolume = item.Volume;
                                    currentBegintTime = item.BeginTime;
                                    calcNextKlineDate(currentBegintTime);
                                    lastKline = item;
                                } else if (nextBegintTime && nextBegintTime == item.BeginTime) {
                                    //更新下一跟K线
                                    // console.log('next');
                                    _maxVolume = 0;
                                    _preVolume = 0;
                                    currentBegintTime = nextBegintTime;
                                    calcNextKlineDate(currentBegintTime);
                                    item.BeginTime = currentBegintTime;
                                    lastKline = item;
                                } else {
                                    //1m推送(需要更新lastKline中的时间等)
                                    if(item.Volume < _preVolume){
                                        _maxVolume = _preVolume + _maxVolume;
                                    }
                                    lastKline.HighestPrice = !lastKline.HighestPrice ? item.HighestPrice : Number(item.HighestPrice) > Number(lastKline.HighestPrice) ? item.HighestPrice : lastKline.HighestPrice;
                                    lastKline.LowestPrice = !lastKline.LowestPrice ? item.LowestPrice : Number(item.LowestPrice) < Number(lastKline.LowestPrice) ? item.LowestPrice : lastKline.LowestPrice;
                                    lastKline.ClosePrice = item.ClosePrice;
                                    lastKline.Volume = _maxVolume + item.Volume;
                                    _preVolume = item.Volume;
                                }
                                if (lastKline && lastKline.BeginTime){
                                    postMessage({
                                        type:type,
                                        action:'Kline',
                                        value:lastKline
                                    })
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}


function checkPingPong(){
    // 检测pingPong是否异常(连接是否异常)
    if(pingCount - pongCount >= 2 && pageStatus){
        pingCount = 0;
        pongCount = 0;
        clearInterval(pingPongTimer);
        clearTimeout(connectTimer);
        if(publicSocket) publicSocket.close();
        publicSocket = null;
        // panList = [];
        tradeList = [];
        postMessage({
            type:type || 'SwapU',
            action:'systemStatus',
            value:4
        })
        setTimeout(()=>{
            // console.log(33333)
            publicConnect().then(res => {
                // 心跳异常重新连接后
                // subByCache();
            })
        },2000)
    }
}

function sendPing(){
    // 发送ping
    if(!pageStatus) return
    // console.log(4444)
    publicConnect().then(function(){
        
    }).finally(e => {
        publicSocket.send('ping');
        pingCount++;
        // clearInterval(pingPongTimer);
        // pingPongTimer = setTimeout(sendPing,5000);
        checkPingPong();
    })
}

function publicConnect(){
    // 连接socket操作
    return new Promise(resolve => {
        if(publicSocket && publicSocket.readyState === 1){
            // socket连接正常
            resolve();
            return
        }
        if(publicSocket && publicSocket.readyState != 1){
            // 连接异常
            publicSocket.close();
            postMessage({
                type:type || 'SwapU',
                action:'systemStatus',
                value:2
            })
            setTimeout(() => {
                connect();
            },1500)
        }
        if(!publicSocket) connect();
        function connect(){
            try{
                clearInterval(pingPongTimer);
                clearTimeout(connectTimer);
                postMessage({
                    type:type || 'SwapU',
                    action:'systemStatus',
                    value:3
                })
                publicSocket = new WebSocket(apiUrl.swapPublicWs);
                publicSocket.onopen = function(){
                    //连接成功
                    pingCount = 0;
                    pongCount = 0;
                    connectErrTimes = 0;
                    clearInterval(pingPongTimer);
                    clearTimeout(connectTimer);
                    // panList = [];
                    // setTimeout(()=>{
                    //     postMessage({
                    //         type:type || 'SwapU',
                    //         action:'reloadKline'
                    //     })
                    // },100)
                    postMessage({
                        type:type || 'SwapU',
                        action:'systemStatus',
                        value:1
                    });
                    postMessage({
                        type:type || 'SwapU',
                        action:'connectErrInfo',
                        value:false
                    });
                    function sendInit(){
                        if(publicSocket && publicSocket.readyState === 1){
                            publicSocket.send('zip=1');
                            subByCache();
                            clearInterval(pingPongTimer);
                            clearTimeout(connectTimer)
                            pingPongTimer = setInterval(()=>{
                                sendPing();
                            },5000)
                            resolve();
                        }else{
                            setTimeout(()=>{
                                sendInit();
                            },500)
                        }
                    }
                    sendInit();
                }
                publicSocket.onmessage = calc;
                publicSocket.onerror = function(err){
                    connectErrTimes++;
                    postMessage({
                        type:type || 'SwapU',
                        action:'systemStatus',
                        value:4
                    });
                    if(connectErrTimes >= 3){
                        //提示连接异常
                        postMessage({
                            type:type || 'SwapU',
                            action:'connectErrInfo',
                            value:true
                        });
                        postMessage({
                            type:type || 'SwapU',
                            action:'systemStatus',
                            value:2
                        });
                    }
                }
                // 延迟检测是否连接成功
                connectTimer = setTimeout(()=>{
                    publicSocket.close();
                    postMessage({
                        type:type || 'SwapU',
                        action:'systemStatus',
                        value:2
                    })
                    setTimeout(() => {
                        connect();
                    },4000)
                },baseTimeout)
            }catch(e){
                console.log(e)
            }
        }
    })
}

let onloadTime = +new Date();
function subByCache(){
    // 根据缓存订阅信息重新订阅
    if(subByCacheTime && +new Date() - subByCacheTime <= 1500) return
    subByCacheTime = +new Date();
    connectErrTimes = 0;
    checkWs().then(res => {
        if(currentIdCacheMsg.action === '1') subCurrentId(currentIdCacheMsg.action,'',9);
        if(tradeListCacheMsg.action === '1') subTradeList(tradeListCacheMsg.action);
        if(panListCacheMsg.action === '1') subPanList(panListCacheMsg.action);
        subCoinListPrice(liveList,[]);
        //通知K线重新加载
        if(+new Date() - onloadTime > 3000){
            postMessage({
                type:type,
                action:'reloadKline'
            })
        }
    }).catch(e => {});
}

function subCurrentId(action,_c,_LocalNo){
    // 订阅(退订)指定币种实时价格
    let _currentId = _c || currentId;
    if(!_currentId || !_LocalNo) return
    checkWs().then(() => {
        if(action == '1'){
            publicSocket.send(JSON.stringify({
                SendTopicAction:{
                    Action: "2",
                    FilterValue: "DeepCoin_" + _currentId,
                    LocalNo: _LocalNo,
                    ResumeNo: -2,
                    TopicID: "7"
                }
            }))
        }
        publicSocket.send(JSON.stringify({
            SendTopicAction:{
                Action: action || "1",
                FilterValue: "DeepCoin_" + _currentId,
                LocalNo: _LocalNo,
                ResumeNo: -2,
                TopicID: "7"
            }
        }))
    }).catch(e => {});
}

function subKline(action,value){
    // 订阅(退订)K线价格
    if(!currentId && !value) return
    checkWs().then(() => {
        publicSocket.send(JSON.stringify({
            SendTopicAction:{
                Action: action || '1',
                FilterValue:'DeepCoin_' + currentId + '_' + (value || klineCacheMsg.value),
                LocalNo: 6,
                ResumeNo: -1,
                TopicID: '11',
            }
        }));
    }).catch(e => {});
}

function subTradeList(action){
    // 订阅(退订)实时成交
    if(!currentId) return
    checkWs().then(() => {
        tradeList = [];
        publicSocket.send(JSON.stringify({
            SendTopicAction:{
                Action: action || '1',
                FilterValue: "DeepCoin_"+currentId,
                LocalNo: 5,
                ResumeNo: -30,
                TopicID: "2"
            }
        }));
        // marketListTimerInterval(action);
        //若是订阅，则退订盘口
        if(action === '1' && panListCacheMsg.action==='1') {
            panListCacheMsg.action = '2';
            subPanList(panListCacheMsg.action);
        }
    }).catch(e => {});
}

function subPanList(action){
    // 订阅(退订)盘口
    if(!currentId) return
    // 如果是整数，则保留一位小数
    let newDeepValue = deepValue;
    if(newDeepValue && !newDeepValue.toString().includes('.')){
        newDeepValue = newDeepValue + '.0';
    }
    checkWs().then(() => {
        // 先退订
        if(panListCacheMsg.InstrumentID && action == '1'){
            publicSocket.send(JSON.stringify({
                SendTopicAction:{
                    Action: '2',               // 订阅操作 '0':Clear/全部退订; '1':Sub/订阅 '2':UnSub/退订
                    FilterValue: "DeepCoin_"+currentId+'_'+newDeepValue,
                    LocalNo: 4,                          // 大于0，自定义,一次会话中不能重复
                    ResumeNo: -2,                        // 续传号:0是从头开始,-1是从服务端最新位置续传
                    TopicID: "25"
                }
            }));
        }
        // panListCacheMsg.InstrumentID
        publicSocket.send(JSON.stringify({
            SendTopicAction:{
                Action: action || '1',               // 订阅操作 '0':Clear/全部退订; '1':Sub/订阅 '2':UnSub/退订
                FilterValue: "DeepCoin_"+currentId+'_'+newDeepValue,
                LocalNo: 4,                          // 大于0，自定义,一次会话中不能重复
                ResumeNo: -2,                        // 续传号:0是从头开始,-1是从服务端最新位置续传
                TopicID: "25"
            }
        }));
        //若是订阅，则退订实时成交
        if(action === '1' && tradeListCacheMsg.action==='1') {
            tradeListCacheMsg.action = '2';
            subTradeList(tradeListCacheMsg.action);
        }
    }).catch(e => {});
}

function checkWs(){
    // 检测ws是否连接成功
    return new Promise((resolve,reject) => {
        if(!pageStatus){
            reject('');
            return
        }
        function check(){
            // console.log('checkWs1')
            if(publicSocket && publicSocket.readyState === 1){
                resolve()
            }else{
                setTimeout(()=>{
                    check()
                },500)
            }
        }
        check();
    })
}


function subCoinListPrice(n,o){
    // 订阅币种价格(先退订可能的币种，再订阅新的)
    // console.log(n,o)
    checkWs().then(res => {
        for(let item of o){
            let find = n.find(ele => ele.InstrumentID === item.InstrumentID);
            if(!find){
                let obj = item.Type==='SwapU'?SwapUObj[item.InstrumentID]:item.Type==='SwapB'?SwapBObj[item.InstrumentID]:item.Type==='SwapC'?SwapCObj[item.InstrumentID]:SwapObj[item.InstrumentID];
                subCurrentId('2',item.InstrumentID,obj?obj.LocalNo:'')
            }
        }
        for(let item of n){
            let find = o.find(ele => ele.InstrumentID === item.InstrumentID);
            if(!find){
                let obj = item.Type==='SwapU'?SwapUObj[item.InstrumentID]:item.Type==='SwapB'?SwapBObj[item.InstrumentID]:item.Type==='SwapC'?SwapCObj[item.InstrumentID]:SwapObj[item.InstrumentID];
                subCurrentId('1',item.InstrumentID,obj?obj.LocalNo:'')
            }
        }
    }).catch(e => {});
}

// 关闭websocket连接
function closeWs(){
    setTimeout(()=>{
        pingCount = 0;
        pongCount = 0;
        clearInterval(pingPongTimer);
        clearTimeout(connectTimer);
        if(publicSocket) publicSocket.close();
        publicSocket = null;
        tradeList = [];
        postMessage({
            type:type || 'SwapU',
            action:'systemStatus',
            value:4
        })
    },600)
}

//监听主线传来的合约信息(只处理 {type:'Swap' || 'SwapU'}类型)
self.addEventListener('message', function (e) {
    let res = e.data;
    if(typeof res === 'object' && !Array.isArray(res) && (res.type === 'Swap' || res.type === 'SwapU' || res.type === 'SwapC' || res.type === 'SwapB' || res.type === 'SwapMarketData' || res.type === 'SwapSpot')){
        // console.log(res)
        if(res.action === 'SwapUList' && Array.isArray(res.value) && res.value.length){
            // 缓存所有USDT永续币种信息
            for(let item of res.value){
                SwapUObj[item.InstrumentID] = item;
            }
        }
        if(res.action === 'SwapCList' && Array.isArray(res.value) && res.value.length){
            // 缓存所有USDC永续币种信息
            for(let item of res.value){
                SwapCObj[item.InstrumentID] = item;
            }
        }
        if(res.action === 'SwapBList' && Array.isArray(res.value) && res.value.length){
            // 缓存所有BUSD永续币种信息
            for(let item of res.value){
                SwapBObj[item.InstrumentID] = item;
            }
        }
        if(res.action === 'SwapList' && Array.isArray(res.value) && res.value.length){
            // 缓存所有币本位币种信息
            for(let item of res.value){
                SwapObj[item.InstrumentID] = item;
            }
        }
        if(res.action === 'subPanList'){
            // 订阅(退订)盘口
            type = res.type;
            if(res.currentId){
                if(res.currentId != currentId) tradeList = [];
                currentId = res.currentId;
                if(res.value==='sub') currentConfig = type==='SwapU'?SwapUObj[currentId]:type==='Swap'?SwapObj[currentId]:type==='SwapC'?SwapCObj[currentId]:type==='SwapB'?SwapBObj[currentId]:{};
            }
            panListCacheMsg.InstrumentID = res.currentId;
            panListCacheMsg.action = res.value==='sub'?'1':'2';
            deepValue = res.deepValue || deepValue;
            // 计算盘口小数位
            let _splitPriceNum = deepValue.toString().split('.')[1];
            panPriceNum = deepValue >= 1?0:_splitPriceNum?_splitPriceNum.length:2;
            if(process.env.DOT_ENV != 'production' && process.env.DOT_ENV != 'prod'){
                panList = [];
                sendOrderBook();
            }

            subPanList(panListCacheMsg.action);
        }
        if(res.action === 'subTradeList'){
            // 订阅(退订)实时成交
            type = res.type;
            // 先执行退订
            let _tradeSub = res.value==='sub'?'1':'2';
            if(_tradeSub === '2'){
                subTradeList('2');
            }
            if(res.currentId) {
                if(res.currentId != currentId) tradeList = [];
                currentId = res.currentId;
                if(res.value==='sub') currentConfig = type==='SwapU'?SwapUObj[currentId]:type==='Swap'?SwapObj[currentId]:type==='SwapC'?SwapCObj[currentId]:type==='SwapB'?SwapBObj[currentId]:{};
            }
            tradeListCacheMsg.action = res.value==='sub'?'1':'2';
            subTradeList(tradeListCacheMsg.action);
        }
        if(res.action === 'Kline'){
            // 订阅(退订)K线
            type = res.type;
            // 先执行退订
            if(klineCacheMsg.action != '-1' && klineCacheMsg.value){
                subKline('2',klineCacheMsg.value);
            }
            if(res.subInfo) klineCacheMsg.action = res.subInfo==='sub'?'1':'2';
            if(res.value) klineCacheMsg.value = res.value;
            if(res.currentId) {
                currentId = res.currentId;
                if(klineCacheMsg.action==='1') currentConfig = type==='SwapU'?SwapUObj[currentId]:type==='Swap'?SwapObj[currentId]:type==='SwapC'?SwapCObj[currentId]:type==='SwapB'?SwapBObj[currentId]:{};
            }
            subKline(klineCacheMsg.action,klineCacheMsg.value);
        }
        if(res.action === 'subCurrentId'){
            // 订阅(退订)当前币种价格
            type = res.type;
            if(res.subInfo) currentIdCacheMsg.action = res.subInfo==='sub'?'1':'2';
            if(res.value) {
                if(res.value != currentId) tradeList = [];
                currentId = res.value;
                if(currentIdCacheMsg.action==='1') currentConfig = type==='SwapU'?SwapUObj[currentId]:type==='Swap'?SwapObj[currentId]:type==='SwapC'?SwapCObj[currentId]:type==='SwapB'?SwapBObj[currentId]:{};
            }
            subCurrentId(currentIdCacheMsg.action,'',9)
        }
        if(res.action === 'pageRouter'){
            router = res.value;
            // console.log(router)
            // console.log(publicSocket)
            if(wsRouter.Swap.includes(router) || router.includes('/koldetail')) {
                if(!publicSocket || publicSocket.readyState != 1){
                    // console.log(111111)
                    publicConnect().then(res => {
                        // console.log(currentIdCacheMsg.action)
                        // console.log(tradeListCacheMsg.action)
                        // console.log(panListCacheMsg.action)
                        // console.log(liveList)
                        // subByCache();
                    })
                }
            }else{
                closeWs();
            }
        }
        if(res.action === 'sendResolution'){
            // K线周期
            resolution = res.value;
            lastKline = {};
            nextKlineDate = '';
            currentBegintTime = '';
            nextBegintTime = '';
        }
        if(res.action === 'sendTimeNav'){
            // 周期列表
            timeNav = res.value;
        }
        if(res.action === 'SwapLiveList'){
            // 订阅指定币种实时价格
            let _value = res.value.filter(item => !item.InstrumentID.includes('/'));
            subCoinListPrice(_value,liveList);
            liveList = _value;
        }
        if(res.action === 'pageStatus'){
            // 页面是否显示在前台
            let currentPageStatus = res.value === 'show'?true:false;
            if(pageStatus && !currentPageStatus){
                // 从前台返回到后台
                closeWs();
                if(router.includes('Swap') && type && currentId) getPrice();
            }
            if(!pageStatus && currentPageStatus){
                // 从后台返回前台
                clearInterval(getPriceByHttpTimer);
                if(wsRouter.Swap.includes(router) || router.includes('/koldetail')){
                    publicConnect().then(res => {
                        // subByCache();
                    })
                }
            }
            pageStatus = currentPageStatus;
        }
    }
}, false);

// setInterval(()=>{
    // if(publicSocket) console.log(publicSocket.readyState)
    // publicConnect().then(res => {
    //     subByCache();
    // })
// },6000)

function getPrice(){
    clearInterval(getPriceByHttpTimer);
    getPriceByHttpTimer = setInterval(()=>{
        $http.get(`${apiUrl.wapi}common/price-by-option`,{[type]:currentId}).then(res => {
            if(res.retCode === 0 && res.retData && res.retData.data){
                let obj = res.retData.data;
                try{
                    let Price = obj[type][0].LastPrice;
                    Price = countNum(Price,currentConfig.PriceNum);
                    postMessage({
                        type:type,
                        action:'refreshPrice',
                        value:{
                            Price:Price,
                            InstrumentName:currentConfig.InstrumentName
                        }
                    })
                }catch(e){

                }
            }
        })
    },10*1000)
}